/*
ID: icerupt1
PROG: charrec
LANG: C++11
*/

/* solution
 *
 * interesting。
 * 动态规划。直接dp可能计算了很多无用状态，记忆化搜索比较好。
 * 另外预处理一下输入和字典每行的相同字符数，才不会超时。
 * 
*/
#include <fstream>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>

std::ifstream fin {"charrec.in" };
std::ifstream font_in {"font.in" };
std::ofstream fout{"charrec.out"};

int const maxn = 1207;
int const maxc = 64;
int const font_c = 27;
int f[maxn][maxc];
int same_c[font_c][22][maxn];
char g[maxn][maxn];
int path[maxn][maxn];
int n;

std::vector<std::vector<std::string>> font;
std::vector<std::string> da;

void init()
{
	font_in >> n;
	font.resize(font_c);
	for (int i = 0; i < font_c; i++) {
		font[i].resize(20);
		for (int j = 0; j < 20; j++)
			font_in >> font[i][j];
	}
}

int string_same(std::string s1, std::string s2)
{
	int tmp = 0;
	for (int i = 0; i < (int)s1.size(); i++) {
		if (s1[i] == s2[i]) tmp++; }
	return tmp;
}

int compare(int start, int len, char & ch)
{
	int same = 0;
	for (int c/*haracter*/ = 0; c < 27; c++) {
		if (len == 20) {
			int tmp = 0;
			for (int i = 0; i < 20; i++)
				tmp += same_c[c][i][start + i];
			if (tmp > same) {
				same = tmp;
				ch = ((c == 0) ? ' ' : char('a' + c - 1));
			}
		//	std::cout << char('a' + c - 1) << ' ' << tmp << '\n';
		} else
		if (len == 21) {
			for (int i = 0; i < 20; i++) {
				int tmp = 0;
				for (int j = 0; j < 20; j++) {
					if (j < i) tmp += same_c[c][j][start + j];
					else
					if (j >= i) tmp += same_c[c][j][start + j + 1];
				}
				if (tmp > same) {
					same = tmp;
					ch = ((c == 0) ? ' ' : char('a' + c - 1));
				}
			}
		} else
		if (len == 19) {
			for (int i = 0; i < 20; i++) {
				int tmp = 20;
				for (int j = 0; j < 20; j++) {
					if (j < i) tmp += same_c[c][j][start + j];
					else
					if (j > i) tmp += same_c[c][j][start + j - 1];
				}
				if (tmp > same) {
					same = tmp;
					ch = ((c == 0) ? ' ' : char('a' + c - 1));
				}
			}
		}

	}
//	if (400 - same > 120) return 0;
	if (same + 120 < 400) return 1;
	return same;
}

int dfs(int i, int j)
{
	if (f[i][j]) return f[i][j];
	if (i < 19) return 0;
	if (j == 0) return 0;
	char ch1 = '!', ch2 = '!', ch3 = '!';
	int t1 = 0, t2 = 0, t3 = 0;
	t1 = dfs(i-19, j-1) + compare(i-19, 19, ch1);
	if (i >= 20) t2 = dfs(i-20, j-1) + compare(i-20, 20, ch2);
	if (i >= 21) t3 = dfs(i-21, j-1) + compare(i-21, 21, ch3);

	if (t1 > f[i][j]) {
		f[i][j] = t1; g[i][j] = ch1; path[i][j] = i-19;
	}
	if (t2 > f[i][j]) {
		f[i][j] = t2; g[i][j] = ch2; path[i][j] = i-20;
	}
	if (t3 > f[i][j]) {
		f[i][j] = t3; g[i][j] = ch3; path[i][j] = i-21;
	}

	return f[i][j];
}

void init_same_c()
{
	for (int c = 0; c < font_c; c++)
		for (int i = 0; i < 20; i++)
			for (int j = 0; j < n; j++)
				same_c[c][i][j] = string_same(font[c][i], da[j]);
}

int main()
{
	std::ios::sync_with_stdio(false);
	init();
	fin >> n; da.resize(n);
	for (int i = 0; i < n; i++) fin >> da[i];

	init_same_c();

	int tot, max = 0;
	for (int i = int(n/21); i <= int(n/19); i++)
		if (dfs(n, i) > max) { tot = i; max = f[n][i]; }

	std::string ans;
	for (int pos = n; tot; tot--) {
		ans += g[pos][tot];
		pos = path[pos][tot];
	}
	std::reverse(ans.begin(), ans.end());
	std::cout << ans << '\n';
	std::cout << ans.size() << '\n';
	fout << ans << '\n';
}

